#include <iostream>
#include <cstring>
#include <string>

using namespace std;

int utf8ChineseLength(const char* str) {
    int len = strlen(str);
    int count = 0;
    for (int i = 0; i < len; ) {
        if ((str[i] & 0xF0) == 0xF0) { // 4 字节 UTF-8 编码
            count++;
            i += 4;
        }
        else if ((str[i] & 0xE0) == 0xE0) { // 3 字节 UTF-8 编码
            count++;
            i += 3;
        }
        else if ((str[i] & 0xC0) == 0xC0) { // 2 字节 UTF-8 编码
            count++;
            i += 2;
        }
        else { // 1 字节 ASCII 字符
            count++;
            i += 1;
        }
    }
    return count;
}

// 一个辅助函数，用来判断一个字节是否是UTF-8编码的首字节
bool is_utf8_lead_byte(unsigned char byte) {
  return (byte & 0xC0) != 0x80;
}

// 一个辅助函数，用来根据首字节判断一个UTF-8编码的字符占用的字节数
int utf8_char_size(unsigned char lead_byte) {
  if ((lead_byte & 0x80) == 0)
    return 1; // 单字节字符
  if ((lead_byte & 0xE0) == 0xC0)
    return 2; // 双字节字符
  if ((lead_byte & 0xF0) == 0xE0)
    return 3; // 三字节字符
  if ((lead_byte & 0xF8) == 0xF0)
    return 4; // 四字节字符
  return -1; // 非法的首字节
}

/*
// 主函数，用来截取一个UTF-8编码的字符串，保证中文字符的完整性
std::string_view utf8_substr(const std::string& str, size_t start, size_t len) {
  // 检查参数是否合法
  if (start >= str.size() || len == 0)
    return "";

  // 找到起始位置对应的字节索引
  size_t start_byte = 0;
  while (start > 0 && start_byte < str.size()) {
    start_byte++;
    if (is_utf8_lead_byte(str[start_byte]))
      start--;
  }

  // 找到结束位置对应的字节索引
  size_t end_byte = start_byte;
  while (len > 0 && end_byte < str.size()) {
    end_byte++;
    if (is_utf8_lead_byte(str[end_byte]))
      len--;
  }

  // 返回截取后的字符串视图
  return std::string_view(&str[start_byte], end_byte - start_byte);
}
*/
// 获取一个UTF-8编码的字符串的长度（以字符为单位）
size_t utf8_length(const std::string& str) {
  
  size_t len = 0;
  
  for (size_t i = 0; i < str.size(); i++) {
    if (is_utf8_lead_byte(str[i])) len++;
  }
  
  return len;
}

// 判断字符串是否以另一个字符串结尾
bool endsWith(const string& str, const string& suffix) {
  // 如果后缀长度大于字符串长度，返回false
  if (suffix.size() > str.size()) {
    return false;
  }
  // 使用find函数从字符串开头开始查找后缀
  size_t pos = str.find(suffix);
  // 如果找到了，并且位置正好是字符串长度减去后缀长度，返回true
  if (pos != string::npos && pos == str.size() - suffix.size()) {
    return true;
  }
  // 否则，返回false
  return false;
}